﻿using HttpRequestTool;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Web;

/// <summary>
/// HttpWebRequest 助手
/// </summary>
class HttpWebHelper
{
    #region Base Get Post

    /// <summary>
    /// Get方式提交或获取网络数据
    /// </summary>
    /// <param name="url"></param>
    /// <param name="param"></param>
    /// <param name="Cookies"></param>
    /// <returns></returns>
    public static HttpWebResponse Get(string url, Dictionary<string, string> param = null, Dictionary<string, string> Cookies = null)
    {
        Uri uri = new Uri(url);

        param = param == null ? new Dictionary<string, string>() : param;
        string pStr = string.Empty;
        foreach (KeyValuePair<string, string> kvp1 in param)
        {
            pStr += string.Format("{0}{1}={2}", string.IsNullOrEmpty(pStr) ? "" : "&", kvp1.Key, kvp1.Value);
        }

        if (!string.IsNullOrEmpty(pStr))
        {
            url = url + (string.IsNullOrEmpty(uri.Query) ? "?" : "&") + pStr;
        }


        HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
        request.Method = "GET";
        request.Timeout = 900000;//15分钟
        //如果没有 下面这行代码 将获取不到相应的Cookie （response.Cookies）  
        //其实 不添加这行代码对于获取 数据没有影响，但是过后的POST操作会用到相应的Cookie  
        request.CookieContainer = new CookieContainer();
        //以下两行对于获取Cookie 对于本次测试 没有影响  
        CookieCollection cc = new CookieCollection();

        Cookies = Cookies == null ? new Dictionary<string, string>() : Cookies;
        foreach (KeyValuePair<string, string> kvp in Cookies)
        {
            cc.Add(new Cookie(kvp.Key, kvp.Value, "/", uri.Host));
        }

        if(HttpContext.Current != null){
            //默认增加登录的Session cookie
            string LoginUserInfo = HttpContext.Current.Request["LoginUserInfo"] ?? string.Empty;
            if (!string.IsNullOrEmpty(LoginUserInfo) && !Cookies.ContainsKey("LoginUserInfo"))
            {
                cc.Add(new Cookie("LoginUserInfo", LoginUserInfo, "/", uri.Host));
            }
        }
        request.CookieContainer.Add(cc);

        return (HttpWebResponse)request.GetResponse();


    }

    /// <summary>
    /// Post方式提交或获取网络数据
    /// </summary>
    /// <param name="url">url地址</param>
    /// <param name="strPostdata">发送的数据</param>
    /// <returns></returns>
    public static HttpWebResponse Post(string url, Dictionary<string, object> param = null, Dictionary<string, string> Cookies = null)
    {
        try
        {

            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = "POST";
            request.Timeout = 900000;//15分钟
            request.ContentType = "application/x-www-form-urlencoded";
            //如果没有 下面这行代码 将获取不到相应的Cookie （response.Cookies）  
            request.CookieContainer = new CookieContainer();

            CookieCollection cc = new CookieCollection();
            Uri uri = new Uri(url);
            Cookies = Cookies == null ? new Dictionary<string, string>() : Cookies;
            foreach (KeyValuePair<string, string> kvp in Cookies)
            {
                cc.Add(new Cookie(kvp.Key, kvp.Value, "/", uri.Host));
            }

            //默认增加登录的Session cookie
            if (HttpContext.Current != null)
            {
                string LoginUserInfo = HttpContext.Current.Request["LoginUserInfo"] ?? string.Empty;
                if (!string.IsNullOrEmpty(LoginUserInfo) && !Cookies.ContainsKey("LoginUserInfo"))
                {
                    cc.Add(new Cookie("LoginUserInfo", LoginUserInfo, "/", uri.Host));
                }
            }

            request.CookieContainer.Add(cc);

            if (param != null)
            {
                string strPostdata = "";
                foreach (KeyValuePair<string, object> kvp in param)
                {
                    if (!string.IsNullOrEmpty(kvp.Key))
                    {
                        strPostdata += (strPostdata == "" ? "" : "&") + string.Format("{0}={1}", kvp.Key, Convert.ToString(kvp.Value));
                    }
                }
                if (strPostdata != "")
                {
                    //往服务器写入数据
                    byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strPostdata);
                    request.ContentLength = buffer.Length;
                    request.GetRequestStream().Write(buffer, 0, buffer.Length);
                }

            }

            //获取服务端返回
            return (HttpWebResponse)request.GetResponse();

        }
        catch (Exception exp)
        {
            throw exp;
        }
    }



    /// <summary>
    /// Get方式提交或获取网络数据
    /// </summary>
    /// <param name="url"></param>
    /// <param name="param"></param>
    /// <param name="Cookies"></param>
    /// <returns></returns>
    public static string Get2(string url, Dictionary<string, string> param = null, Dictionary<string, string> Cookies = null)
    {
        HttpWebResponse resp = Get(url, param, Cookies);
        if (resp != null)
        {
            using (StreamReader reader = new StreamReader(resp.GetResponseStream(), System.Text.Encoding.UTF8))
            {
                return reader.ReadToEnd();
            }
        }
        else
        {
            return null;
        }
    }

    /// <summary>
    /// Post方式提交或获取网络数据
    /// </summary>
    /// <param name="url">url地址</param>
    /// <param name="param">发送的数据</param>
    /// <param name="Cookies"></param>
    /// <returns></returns>
    public static string Post2(string url, Dictionary<string, object> param = null, Dictionary<string, string> Cookies = null)
    {
        HttpWebResponse resp = Post(url, param, Cookies);
        if (resp != null)
        {
            using (StreamReader reader = new StreamReader(resp.GetResponseStream(), System.Text.Encoding.UTF8))
            {
                return reader.ReadToEnd();
            }
        }
        else
        {
            return null;
        }
    }

    /// <summary>
    /// Post 一个可序列化的对象
    /// </summary>
    /// <param name="url"></param>
    /// <param name="param">可序列化的对象参数</param>
    /// <param name="Cookies"></param>
    /// <param name="Headers"></param>
    /// <returns></returns>
    public static HttpWebResponse PostJsonObject(string url, object param, Dictionary<string, string> Cookies = null, Dictionary<string, string> Headers = null)
    {
        try
        {

            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = "POST";
            request.Timeout = 900000;//15分钟
            request.ContentType = "application/json";
            request.Accept = "application/json, text/javascript, */*; q=0.01";
            request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36";

            //请求头
            if (Headers != null) {
                foreach (KeyValuePair<string, string> kvp in Headers) {
                    if (!string.IsNullOrEmpty(kvp.Key)) {
                        request.Headers.Add(kvp.Key, kvp.Value);
                    }
                }
            }


            //如果没有 下面这行代码 将获取不到相应的Cookie （response.Cookies）  
            request.CookieContainer = new CookieContainer();

            CookieCollection cc = new CookieCollection();
            Uri uri = new Uri(url);
            Cookies = Cookies == null ? new Dictionary<string, string>() : Cookies;
            foreach (KeyValuePair<string, string> kvp in Cookies)
            {
                cc.Add(new Cookie(kvp.Key, kvp.Value, "/", uri.Host));
            }

            //默认增加登录的Session cookie
            if (HttpContext.Current != null)
            {
                string LoginUserInfo = HttpContext.Current.Request["LoginUserInfo"] ?? string.Empty;
                if (!string.IsNullOrEmpty(LoginUserInfo) && !Cookies.ContainsKey("LoginUserInfo"))
                {
                    cc.Add(new Cookie("LoginUserInfo", LoginUserInfo, "/", uri.Host));
                }
            }

            request.CookieContainer.Add(cc);

            if (param == null)
            {
                throw new Exception("Post的对象参数为空");
            }

            //System.Web.Script.Serialization.JavaScriptSerializer jss = new System.Web.Script.Serialization.JavaScriptSerializer();
            //jss.MaxJsonLength = int.MaxValue; //设置为int的最大值

            string json = JsonHelper.Serialize(param);
            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(json);
            request.ContentLength = buffer.Length;
            request.GetRequestStream().Write(buffer, 0, buffer.Length);

            //获取服务端返回
            return (HttpWebResponse)request.GetResponse();

        }
        catch (Exception exp)
        {
            throw exp;
        }
    }

    /// <summary>
    /// Post 一个可序列化的对象
    /// </summary>
    /// <param name="url"></param>
    /// <param name="param">可序列化的对象参数</param>
    /// <param name="Cookies"></param>
    /// <param name="Headers"></param>
    /// <returns></returns>
    public static string PostJsonObject2(string url, object param, Dictionary<string, string> Cookies = null, Dictionary<string, string> Headers = null)
    {
        HttpWebResponse resp = PostJsonObject(url, param, Cookies, Headers);
        
        if (resp != null)
        {
            using (StreamReader reader = new StreamReader(resp.GetResponseStream(), System.Text.Encoding.UTF8))
            {
                return reader.ReadToEnd();
            }
        }
        else
        {
            return null;
        }
    }

    #endregion


    #region 上传文件

    /// <summary>
    /// 固定长度的随机字符串
    /// </summary>
    /// <param name="length"></param>
    /// <returns></returns>
    private static string GetRandomString(int length)
    {
        char[] charList = {
            '0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F','G','H','I','J','K','L','M',
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
'a','b','c','d','e','f','g','h','i','j','k','l','m',
'n','o','p','q','r','s','t','u','v','w','x','y','z'};

        char[] rev = new char[length];
        Random f = new Random();
        for (int i = 0; i < length; i++)
        {
            rev[i] = charList[Math.Abs(f.Next(127)) % length];
        }
        return new string(rev);
    }

    static bool CheckValidationResult(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate,
        System.Security.Cryptography.X509Certificates.X509Chain chain,
        System.Net.Security.SslPolicyErrors errors)
    {
        return true;
    }

    /// <summary>
    /// 上传一个或多个文件
    /// </summary>
    /// <param name="url">上传地址</param>
    /// <param name="files">文件数据</param>
    /// <param name="paramData">参数</param>
    /// <returns></returns>
    public static string UploadFile(string url, List<UploadFile> files, Dictionary<string, object> paramData = null, Dictionary<string, string> cookies = null, Dictionary<string, string> headers = null)
    {
        using (MemoryStream memoryStream = new MemoryStream())
        {
            System.Text.Encoding _Encoding = System.Text.Encoding.UTF8;
            // 1.分界线
            string boundary = string.Format("----{0}", DateTime.Now.Ticks.ToString("x")),       // 分界线可以自定义参数
                beginBoundary = string.Format("--{0}\r\n", boundary),
                endBoundary = string.Format("\r\n--{0}--\r\n", boundary);
            byte[] beginBoundaryBytes = _Encoding.GetBytes(beginBoundary),
                endBoundaryBytes = _Encoding.GetBytes(endBoundary);
            // 2.组装开始分界线数据体 到内存流中
            memoryStream.Write(beginBoundaryBytes, 0, beginBoundaryBytes.Length);
            // 3.组装 上传文件附加携带的参数 到内存流中
            if (paramData != null && paramData.Count > 0)
            {
                foreach (KeyValuePair<string, object> kvp in paramData)
                {
                    string parameterHeaderTemplate = string.Format("Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}\r\n{2}", kvp.Key, Convert.ToString(kvp.Value), beginBoundary);
                    byte[] parameterHeaderBytes = _Encoding.GetBytes(parameterHeaderTemplate);

                    memoryStream.Write(parameterHeaderBytes, 0, parameterHeaderBytes.Length);
                }
            }

            for (int ind = 0; ind < files.Count; ind++)
            {
                UploadFile file = files[ind];

                // 4.组装文件头数据体 到内存流中
                string fileHeaderTemplate = string.Format("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: application/octet-stream\r\n\r\n",
                    "file_" + ind, file.Name);

                byte[] fileHeaderBytes = _Encoding.GetBytes(fileHeaderTemplate);
                memoryStream.Write(fileHeaderBytes, 0, fileHeaderBytes.Length);


                // 5.组装文件流 到内存流中
                if (file.FileBytes != null && file.FileBytes.Length > 0)
                {
                    memoryStream.Write(file.FileBytes, 0, file.FileBytes.Length);
                }
                else
                {
                    byte[] buffer = new byte[1024 * 1024 * 1];
                    int size = file.FileStream.Read(buffer, 0, buffer.Length);
                    while (size > 0)
                    {
                        memoryStream.Write(buffer, 0, size);
                        size = file.FileStream.Read(buffer, 0, buffer.Length);
                    }
                }

            }

            // 6.组装结束分界线数据体 到内存流中
            memoryStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);

            // 7.获取二进制数据
            byte[] postBytes = memoryStream.ToArray();

            // 8.HttpWebRequest 组装
            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(new Uri(url, UriKind.RelativeOrAbsolute));
            webRequest.Method = "POST";
            webRequest.Timeout = 300000;
            
            //请求头
            if (headers != null) {
                foreach (KeyValuePair<string, string> kvp in headers) {
                    if (!string.IsNullOrEmpty(kvp.Key)) {
                        webRequest.Headers.Add(kvp.Key, kvp.Value);
                    }
                }
            }

            // Cookies
            if (cookies != null)
            {
                CookieCollection cc = new CookieCollection();
                Uri uri = new Uri(url);
                foreach (KeyValuePair<string, string> kvp in cookies)
                {
                    if (!string.IsNullOrEmpty(kvp.Key))
                    {
                        cc.Add(new Cookie(kvp.Key, kvp.Value, "/", uri.Host));
                    }
                }
                
                webRequest.CookieContainer.Add(cc);
            }
            
            webRequest.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
            webRequest.ContentLength = postBytes.Length;
            
            if (System.Text.RegularExpressions.Regex.IsMatch(url, "^https://"))
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
                ServicePointManager.ServerCertificateValidationCallback = CheckValidationResult;
            }

            // 9.写入上传请求数据
            using (Stream requestStream = webRequest.GetRequestStream())
            {
                requestStream.Write(postBytes, 0, postBytes.Length);
                requestStream.Close();
            }

            // 10.获取响应
            using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
            {
                using (StreamReader reader = new StreamReader(webResponse.GetResponseStream(), _Encoding))
                {
                    string body = reader.ReadToEnd();
                    reader.Close();
                    return body;
                }
            }
        }

    }

    /// <summary>
    /// 上传一个文件
    /// </summary>
    /// <param name="url">上传地址</param>
    /// <param name="file">文件数据</param>
    /// <param name="paramData">参数</param>
    /// <returns></returns>
    public static string UploadFile(string url, UploadFile file, Dictionary<string, object> paramData = null)
    {
        List<UploadFile> files = new List<UploadFile>();
        files.Add(file);
        return UploadFile(url, files, paramData);
    }

    /// <summary>
    /// 上传一个或多个文件 by 2019-09-05
    /// </summary>
    /// <param name="url">上传地址</param>
    /// <param name="fileKey">装载文件的字段</param>
    /// <param name="files">文件数据</param>
    /// <param name="paramData">参数</param>
    /// <returns></returns>
    public static string UploadFile(string url,string fileKey, List<UploadFile> files, Dictionary<string, object> paramData = null, Dictionary<string, string> cookies = null, Dictionary<string, string> headers = null)
    {
        try
        {
            System.Text.Encoding _Encoding = System.Text.Encoding.UTF8;
            //分界线
            string boundary = string.Format("-------------{0}", DateTime.Now.Ticks.ToString("x"));      // 分界线可以自定义参数
            
            //中间分割线字符串
            string boundaryString = string.Format("\r\n--{0}\r\n", boundary);
            byte[] boundaryBytes = _Encoding.GetBytes(boundaryString);

            // 开始拼数据-------------------------------------------------------------
            MemoryStream contentStream = new MemoryStream();

            // Key-Value数据 携带的参数
            if (paramData != null && paramData.Count > 0)
            {
                string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
                foreach (KeyValuePair<string, object> kvp in paramData)
                {
                    //分割线
                    contentStream.Write(boundaryBytes, 0, boundaryBytes.Length);
                    //Key-Value数据
                    string formitem = string.Format(formdataTemplate, kvp.Key, Convert.ToString(kvp.Value) );
                    byte[] formitembytes = _Encoding.GetBytes(formitem);
                    contentStream.Write(formitembytes, 0, formitembytes.Length);

                }
            }
            
            //文件
            string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
            for (int ind = 0; ind < files.Count; ind++)
            {
                UploadFile file = files[ind];

                //分割线
                contentStream.Write(boundaryBytes, 0, boundaryBytes.Length);

                //文件参数头
                string header = string.Format(headerTemplate, fileKey, file.Name, file.ContentType);
                byte[] headerbytes = _Encoding.GetBytes(header);
                contentStream.Write(headerbytes, 0, headerbytes.Length);

                //文件数据
                if (file.FileBytes != null && file.FileBytes.Length > 0)
                {
                    contentStream.Write(file.FileBytes, 0, file.FileBytes.Length);
                }
                else
                {
                    var buffer = new byte[1024];
                    int bytesRead; // =0
                    while ((bytesRead = file.FileStream.Read(buffer, 0, buffer.Length)) != 0)
                    {
                        contentStream.Write(buffer, 0, bytesRead);
                    }
                }

            }
            
            //结束分割线字符串
            string endBoundaryString = string.Format("\r\n--{0}--\r\n", boundary);
            byte[] endBoundaryBytes = _Encoding.GetBytes(endBoundaryString);

            // 写入最后的结束边界符
            contentStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);

            //内容流转为 byte[]
            contentStream.Position = 0;
            byte[] tempBuffer = new byte[contentStream.Length];
            contentStream.Read(tempBuffer, 0, tempBuffer.Length);
            contentStream.Close();

            // 创建webRequest并设置属性
            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(new Uri(url, UriKind.RelativeOrAbsolute));
            webRequest.Method = "POST";
            webRequest.Timeout = 300000;

            //请求头
            if (headers != null && headers.Count > 0)
            {
                foreach (KeyValuePair<string, string> kvp in headers)
                {
                    if (!string.IsNullOrEmpty(kvp.Key))
                    {
                        webRequest.Headers.Add(kvp.Key, kvp.Value);
                    }
                }
            }

            // Cookies
            if (cookies != null && cookies.Count > 0)
            {
                CookieCollection cc = new CookieCollection();
                Uri uri = new Uri(url);
                foreach (KeyValuePair<string, string> kvp in cookies)
                {
                    if (!string.IsNullOrEmpty(kvp.Key))
                    {
                        cc.Add(new Cookie(kvp.Key, kvp.Value, "/", uri.Host));
                    }
                }

                webRequest.CookieContainer.Add(cc);
            }
            
            webRequest.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
            webRequest.ContentLength = tempBuffer.Length;

            Stream requestStream = webRequest.GetRequestStream();
            requestStream.Write(tempBuffer, 0, tempBuffer.Length);
            requestStream.Close();
            
            if (System.Text.RegularExpressions.Regex.IsMatch(url, "^https://"))
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
                ServicePointManager.ServerCertificateValidationCallback = CheckValidationResult;
            }

            //获取响应
            using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
            {
                using (StreamReader reader = new StreamReader(webResponse.GetResponseStream(), _Encoding))
                {
                    
                    string body = reader.ReadToEnd();
                    reader.Close();
                    webResponse.Close();

                    return body;
                }
            }
            
        }
        catch (Exception exp) {
            throw new Exception("HttpWebHelper.UploadFile 上传一个或多个文件异常。", exp); 
        }
    }
    
    /// <summary>
    /// 上传一个或多个文件 by 2019-09-05
    /// </summary>
    /// <param name="url">上传地址</param>
    /// <param name="fileKey">装载文件的字段</param>
    /// <param name="file">文件数据</param>
    /// <param name="paramData">参数</param>
    /// <returns></returns>
    public static string UploadFile(string url, string fileKey, UploadFile file, Dictionary<string, object> paramData = null)
    {
        List<UploadFile> files = new List<UploadFile>();
        files.Add(file);
        return UploadFile(url, fileKey, files, paramData);
    }
    
    /// <summary>
    /// 上传一个或多个文件 by 2019-09-06
    /// </summary>
    /// <param name="url">上传地址</param>
    /// <param name="files">文件数据</param>
    /// <param name="paramData">参数</param>
    /// <returns></returns>
    public static string UploadFileWithEveryFileKey(string url, List<UploadFile> files, Dictionary<string, object> paramData = null)
    {
        try
        {
            System.Text.Encoding _Encoding = System.Text.Encoding.UTF8;
            //分界线
            string boundary = string.Format("-------------{0}", DateTime.Now.Ticks.ToString("x"));      // 分界线可以自定义参数

            //中间分割线字符串
            string boundaryString = string.Format("\r\n--{0}\r\n", boundary);
            byte[] boundaryBytes = _Encoding.GetBytes(boundaryString);

            // 开始拼数据-------------------------------------------------------------
            MemoryStream contentStream = new MemoryStream();

            // Key-Value数据 携带的参数
            if (paramData != null && paramData.Count > 0)
            {
                string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
                foreach (KeyValuePair<string, object> kvp in paramData)
                {
                    //分割线
                    contentStream.Write(boundaryBytes, 0, boundaryBytes.Length);
                    //Key-Value数据
                    string formitem = string.Format(formdataTemplate, kvp.Key, Convert.ToString(kvp.Value));
                    byte[] formitembytes = _Encoding.GetBytes(formitem);
                    contentStream.Write(formitembytes, 0, formitembytes.Length);

                }
            }

            //文件
            string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
            for (int ind = 0; ind < files.Count; ind++)
            {
                UploadFile file = files[ind];

                //分割线
                contentStream.Write(boundaryBytes, 0, boundaryBytes.Length);

                //文件参数头
                string header = string.Format(headerTemplate,file.FileKey, file.Name, file.ContentType);
                byte[] headerbytes = _Encoding.GetBytes(header);
                contentStream.Write(headerbytes, 0, headerbytes.Length);

                //文件数据
                if (file.FileBytes != null && file.FileBytes.Length > 0)
                {
                    contentStream.Write(file.FileBytes, 0, file.FileBytes.Length);
                }
                else
                {
                    var buffer = new byte[1024];
                    int bytesRead; // =0
                    while ((bytesRead = file.FileStream.Read(buffer, 0, buffer.Length)) != 0)
                    {
                        contentStream.Write(buffer, 0, bytesRead);
                    }
                }

            }

            //结束分割线字符串
            string endBoundaryString = string.Format("\r\n--{0}--\r\n", boundary);
            byte[] endBoundaryBytes = _Encoding.GetBytes(endBoundaryString);

            // 写入最后的结束边界符
            contentStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);

            //内容流转为 byte[]
            contentStream.Position = 0;
            byte[] tempBuffer = new byte[contentStream.Length];
            contentStream.Read(tempBuffer, 0, tempBuffer.Length);
            contentStream.Close();

            // 创建webRequest并设置属性
            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(new Uri(url, UriKind.RelativeOrAbsolute));
            webRequest.Method = "POST";
            webRequest.Timeout = 100000;
            webRequest.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
            webRequest.ContentLength = tempBuffer.Length;

            Stream requestStream = webRequest.GetRequestStream();
            requestStream.Write(tempBuffer, 0, tempBuffer.Length);
            requestStream.Close();

            if (System.Text.RegularExpressions.Regex.IsMatch(url, "^https://"))
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
                ServicePointManager.ServerCertificateValidationCallback = CheckValidationResult;
            }

            //获取响应
            using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
            {
                using (StreamReader reader = new StreamReader(webResponse.GetResponseStream(), _Encoding))
                {
                    string body = reader.ReadToEnd();
                    reader.Close();
                    webResponse.Close();
                    return body;
                }
            }

        }
        catch (Exception exp)
        {
            throw new Exception("HttpWebHelper.UploadFileWithEveryFileKey 上传一个或多个文件异常。", exp);
        }
    }

    /// <summary>
    /// 上传一个或多个文件 by 2019-09-06
    /// </summary>
    /// <param name="url">上传地址</param>
    /// <param name="file">文件数据</param>
    /// <param name="paramData">参数</param>
    /// <returns></returns>
    public static string UploadFileWithEveryFileKey(string url, UploadFile file, Dictionary<string, object> paramData = null) {
        List<UploadFile> files = new List<UploadFile>();
        files.Add(file);
        return UploadFileWithEveryFileKey(url, files, paramData);
    }



    #endregion


}

/// <summary>
/// 上传的文件
/// </summary>
public class UploadFile
{
    /// <summary>
    /// 服务端接收文件的key
    /// </summary>
    public string FileKey = null;
    /// <summary>
    /// 文件名
    /// </summary>
    public string Name = null;
    /// <summary>
    /// 文件流
    /// </summary>
    public Stream FileStream = null;
    /// <summary>
    /// 文件流字节
    /// </summary>
    public byte[] FileBytes;
    /// <summary>
    /// Content-Type 默认为application/octet-stream
    /// </summary>
    public string ContentType {
        get {
            string _ContentType = string.IsNullOrEmpty(Name) ? "" : MimeMapping.GetMimeMapping(Name);
            return string.IsNullOrEmpty(_ContentType) ? "application/octet-stream" : _ContentType;
        }
    }


    public UploadFile() {}
}

/// <summary>
/// 
/// </summary>
/// <typeparam name="T"></typeparam>
[Serializable]
public class ApiReturnData<T> where T : class, new()
{
    public int status;
    public T data;
    public string errorcode;
    public string errormsg;
  
/*
 {
    "status": 1, 
    "data": {
        "user_loginid": "", 
        "user_realname": "管理员", 
        "user_id": 87, 
        "user_img_url": null, 
        "user_type": "0", 
        "user_roleIds": "1,7,8,9,1012,", 
        "user_menuIds": "4,4,3,3,3,2,2,1,1,1,16,16,21,27,28,8,8,9,9,15,17,17,18,29,29,", 
        "user_operationIds": "2,5,5,4,3,3,"
    }, 
    "errorcode": "", 
    "errormsg": ""
}
*/

}

/// <summary>
/// 菜单
/// </summary>
[Serializable]
public class MenuInfo
{
    public string menu_id;
    public string menu_parent_id;
    public string menu_name;
    public string menu_title;
    public string menu_url;

    //"menu_id": 115,
    //"menu_parent_id": 113,
    //"menu_name": "open_platform_mjg",
    //"menu_title": "面肩肱",
    //"menu_remark": null,
    //"menu_icon_url": null,
    //"menu_url": "/open/fshd/patientlist.html",
    //"menu_method": "Get",
    //"app_id": 6,
    //"sort_id": 2,
    //"create_time": "2018-02-26 09:36:06",
    //"update_time": "2018-02-26 09:51:43",
    //"app_title": "开放平台"

}

/// <summary>
/// 操作权限
/// </summary>
[Serializable]
public class OperationInfo
{
    public int op_id;
    public string op_name;
    public string op_title;


    //"op_id": 16,
    //"op_name": "erp_admin_operation_delete",
    //"op_url": "/Operation/Delete",
    //"op_method": "Get",
    //"op_remark": null,
    //"app_id": 1,
    //"sort_id": 99,
    //"create_time": "2017-12-25 14:07:17",
    //"update_time": "2017-12-25 14:07:17",
    //"del_flag": 0,
    //"op_title": "删除操作",
    //"op_icon_url": null

}

